using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;

using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.POI;
using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.Pathing;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;


namespace ARogue
{
    class AltecRogue : CombatRoutine
    {
        public Version version = new Version(0, 7);
        public bool namc()
        {
            if (Me.CurrentTarget != null && !Me.CurrentTarget.IsDead && (Me.CurrentTarget.IsHostile || Me.CurrentTarget.IsNeutral) && Me.CurrentTarget.IsWithinMeleeRange)
                return true;
            return false;
        }        
        public override sealed string Name
        {
            get { return "[BETA] ARAssassination. Version: " + version; }
        }
        public override WoWClass Class
        {
            get { return WoWClass.Rogue; }
        }
        private static LocalPlayer Me { get { return StyxWoW.Me; } }
        private void slog(string format, params object[] args)
        {
            Logging.Write(format, args);
        }
        public override bool WantButton
        {
            get { return true; }
        }
        public override void OnButtonPress()
        {
            ARogue.ARForm f1 = new ARogue.ARForm();
            Logging.Write("Opening Configuration Settings");
            f1.ShowDialog();
        }
        public override void Initialize()
        {
            Logging.Write("Loading");
            Logging.Write("Welcome to [BETA] ARAssassination, Version: {0}", version);
            Logging.Write("Enjoy the new GUI, it can be changed while the bot is running!!");
            Logging.Write(@"Report any bugs / comments / thoughts to: http://www.thebuddyforum.com/honorbuddy-forum/combat-routines/rogue/89825-altecs-rogue-routine.html");
        }

        #region CC_Begin

        public override bool NeedRest
        {
            get
            {
                if (ARSettings.Instance.AlwaysStealth && SpellManager.HasSpell("Stealth") && !Me.HasAura("Stealth") && !Me.IsCasting && !Me.Mounted)
                    if (CastMeUp("Stealth"))
                        Logging.Write("Stealth");
                if (SpellManager.HasSpell("Deadly Poison") && !Me.Mounted && !Me.IsMoving && !Me.IsCasting && (!Me.HasAura("Deadly Poison") || (Me.HasAura("Deadly Poison") && Me.ActiveAuras["Deadly Poison"].TimeLeft.Minutes < 10)))
                    return true;
                if (!SpellManager.HasSpell("Leeching Poison") && SpellManager.HasSpell("Mind-Numbing Poison"))
                    if (!Me.Mounted && !Me.IsMoving && !Me.IsCasting && (!Me.HasAura("Mind-numbing Poison") || (Me.HasAura("Mind-numbing Poison") && Me.ActiveAuras["Mind-numbing Poison"].TimeLeft.Minutes < 10)))
                        return true;
                if (SpellManager.HasSpell("Leeching Poison"))
                    if (!Me.Mounted && !Me.IsMoving && !Me.IsCasting && (!Me.HasAura("Leeching Poison") || (Me.HasAura("Leeching Poison") && Me.ActiveAuras["Leeching Poison"].TimeLeft.Minutes < 10)))
                        return true;
                return false;
            }
        }
        public override void Rest()
        {
            if (!Me.Mounted && !Me.IsMoving && !Me.IsCasting && (!Me.HasAura("Deadly Poison") || (Me.HasAura("Deadly Poison") && Me.ActiveAuras["Deadly Poison"].TimeLeft.Minutes < 10)))
                if (CastMeUp("Deadly Poison"))
                    Logging.Write("Applying Deadly Poison");
            if (!SpellManager.HasSpell("Leeching Poison"))
                if (!Me.Mounted && !Me.IsMoving && !Me.IsCasting && (!Me.HasAura("Mind-numbing Poison") || (Me.HasAura("Mind-numbing Poison") && Me.ActiveAuras["Mind-numbing Poison"].TimeLeft.Minutes < 10)))
                    if (CastMeUp("Mind-numbing Poison"))
                        Logging.Write("Applying Mind-numbing Poison");
            if (SpellManager.HasSpell("Leeching Poison"))
                if (!Me.Mounted && !Me.IsMoving && !Me.IsCasting && (!Me.HasAura("Leeching Poison") || (Me.HasAura("Leeching Poison") && Me.ActiveAuras["Leeching Poison"].TimeLeft.Minutes < 10)))
                    if (CastMeUp("Leeching Poison"))
                        Logging.Write("Applying Leeching Poison");
        }

        #endregion

        #region Pull

        public override void Pull()
        {
            
            RangeCheck();
        }
        public void RangeCheck()
        {
                //Face the target
                if (namc() && !Me.IsSafelyFacing(Me.CurrentTarget))
                {
                    Me.CurrentTarget.Face();
                    Logging.Write("Face Target");
                }

                //Move to the target
                if (ARSettings.Instance.Movement)
                {
                    if (ARSettings.Instance.ShadowStep && Me.CurrentTarget != null && !Me.CurrentTarget.IsDead && (Me.CurrentTarget.IsHostile || Me.CurrentTarget.IsNeutral) && !Me.CurrentTarget.IsWithinMeleeRange)
                        if (CastMeUp("Shadowstep"))
                            Logging.Write("Shadow Step to the target");
                    if (Me.CurrentTarget != null && !Me.CurrentTarget.IsDead && (Me.CurrentTarget.IsHostile || Me.CurrentTarget.IsNeutral) && !Me.CurrentTarget.IsWithinMeleeRange)
                        {
                            MoveBehind(Me.CurrentTarget);
                            Logging.Write("Moving to the target");
                        }
                    if (namc())
                        Navigator.PlayerMover.MoveStop();
                }

                addCount();
                IsTargetBoss();
                if (SpellManager.HasSpell("Stealth") && !Me.HasAura("Stealth") && !Me.IsCasting && !Me.Mounted && Me.Combat == false)
                    if (CastMeUp("Stealth"))
                        Logging.Write("Stealth");
                if (namc() && (Me.GroupInfo.IsInParty || Me.GroupInfo.IsInRaid) && SpellManager.HasSpell("Tricks of the Trade") && SpellManager.CanCast("Tricks of the Trade") && Me.FocusedUnit != null && Me.FocusedUnit.IsAlive)
                {
                    Lua.DoString("RunMacroText('/cast [@focus] Tricks of the Trade');");
                    Logging.Write("Tricks of the Trade on >>" + Me.FocusedUnit.Name + "<<");
                }
                if (SpellManager.HasSpell("Mutilate") && (Me.HasAura("Stealth") || Me.HasAura("Vanish")) && namc() && (Me.CurrentTarget.IsHostile || Me.CurrentTarget.IsNeutral))
                    if (CastMeUp("Mutilate"))
                        Logging.Write("          Mutilate");
                if (!SpellManager.HasSpell("Mutilate") && SpellManager.HasSpell("Cheap Shot") && (Me.HasAura("Stealth") || Me.HasAura("Vanish")) && namc())
                    if (CastMeUp("Cheap Shot"))
                        Logging.Write("          Cheap Shot");
                if (!SpellManager.HasSpell("Mutilate") && !SpellManager.HasSpell("Cheap Shot") && (Me.HasAura("Stealth") || Me.HasAura("Vanish")) && namc())
                    if (CastMeUp("Sinister Strike"))
                        Logging.Write("          Sinister Strike");
                if (namc() && !Me.HasAura("Stealth") && !Me.IsAutoAttacking)
                {
                    Lua.DoString("StartAttack()");
                    Logging.Write("StartAttack");
                }
        }

        #endregion

        #region Add Detection

        public static void MoveBehind(WoWUnit Unit)
        {

            WoWPoint BehindLocation = WoWMathHelper.CalculatePointBehind(Unit.Location, Unit.Rotation, 2.5f);
            Navigator.MoveTo(BehindLocation);
        }
        private int addCount()
        {
            int count = 0;
            foreach (WoWUnit u in ObjectManager.GetObjectsOfType<WoWUnit>(true, true))
            {
                if (u.IsAlive
                    && Me.CurrentTarget != null
                    && u.Guid != Me.Guid
                    && !u.IsFriendly
                    && (u.IsHostile || u.IsNeutral)
                    && !u.IsCritter
                    && (u.Location.Distance(Me.Location) <= 8 || u.Location.Distance2D(Me.Location) <= 8)
                    && (u.IsTargetingMyPartyMember || u.IsTargetingMyRaidMember || u.IsTargetingMeOrPet || u.IsTargetingAnyMinion))
                {
                    count++;
                }
            }
            return count;
        }
        private bool IsTargetBoss()
        {
            if (namc() && Me.CurrentTarget.IsBoss)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        #endregion

        #region Combat

        public override void Combat()
        {
            RangeCheck();
            if (ARSettings.Instance.Kick && namc() && SpellManager.HasSpell("Kick") && SpellManager.CanCast("Kick") && Me.CurrentTarget.IsCasting && Me.CurrentTarget.CanInterruptCurrentSpellCast)
                if (CastMeUp("Kick"))
                { Logging.Write("!! Kick !!"); }
            if (ARSettings.Instance.ArcaneTorrent && SpellManager.HasSpell("Arcane Torrent") && SpellManager.CanCast("Arcane Torrent") && Me.CurrentTarget.Distance < 8 && Me.CurrentTarget.IsCasting && Me.CurrentTarget.CanInterruptCurrentSpellCast)
                if (CastMeUp("Arcane Torrent"))
                { Logging.Write("!! Arcane Torrent !!"); }

            //Energy Regen Mechanic
            if (namc() && SpellManager.HasSpell("Rupture") && Me.ComboPoints > 0 && (!Me.CurrentTarget.HasAura("Rupture") || (Me.CurrentTarget.HasAura("Rupture") && Me.CurrentTarget.ActiveAuras["Rupture"].TimeLeft.TotalSeconds < 3)))
                if (CastMeUp("Rupture"))
                    Logging.Write("Rupture");

            //Autoattack
            if (namc() && !Me.HasAura("Stealth") && !Me.IsAutoAttacking)
            {
                Lua.DoString("StartAttack()");
                Logging.Write("StartAttack");
            }

            //Self-Heals
            if (namc() && SpellManager.HasSpell("Shiv") && Me.HasAura("Leeching Poison") && Me.HealthPercent < 80)
                if (CastMeUp("Shiv"))
                    Logging.Write("!! Shiv !!");
            if (namc() && SpellManager.HasSpell("Recuperate") && Me.ComboPoints > 0 && Me.HealthPercent < 80 && (!Me.HasAura("Recuperate") || Me.ActiveAuras["Recuperate"].TimeLeft.TotalSeconds < 3))
                if (CastMeUp("Recuperate"))
                    Logging.Write("++ Recuperate ++");

            //Boss CoolDowns
            if (IsTargetBoss() || ARSettings.Instance.UseCDs)
            {
                if ((Me.GroupInfo.IsInParty || Me.GroupInfo.IsInRaid) && !Me.HasAura("Stealth"))
                {
                    if (ARSettings.Instance.Vanish && SpellManager.HasSpell("Vanish") && namc() && CastMeUp("Vanish"))
                        Logging.Write("!! Vanish !!");
                    if (ARSettings.Instance.ExposeArmor && SpellManager.HasSpell("Expose Armor") && namc() && !Me.CurrentTarget.HasAura("Weakened Armor") || (Me.CurrentTarget.HasAura("Weakened Armor") && Me.CurrentTarget.ActiveAuras["Weakened Armor"].TimeLeft.TotalSeconds < 3))
                        if (CastMeUp("          Expose Armor"))
                            Logging.Write("!! Expose Armor !!");
                    if (ARSettings.Instance.ShadowBlades && SpellManager.HasSpell("Shadow Blades") && namc() && Me.HasAura("Slice and Dice"))
                        if (CastMeUp("Shadow Blades"))
                            Logging.Write("!! Shadow Blades !!");
                    if (ARSettings.Instance.Vendetta && SpellManager.HasSpell("Vendetta") && namc() && CastMeUp("Vendetta"))
                        Logging.Write("!! Vendetta!");
                    if (ARSettings.Instance.RocketBarrage && SpellManager.HasSpell("Rocket Barrage") && Me.CurrentTarget != null && CastMeUp("Rocket Barrage"))
                        Logging.Write("!! Rocket Barrage !!");
                    if (ARSettings.Instance.BloodFury && SpellManager.HasSpell("Blood Fury") && namc() && CastMeUp("Blood Fury"))
                        Logging.Write("!! Blood Fury !!");
                    if (ARSettings.Instance.Berserking && SpellManager.HasSpell("Berserking") && namc() && CastMeUp("Berserking"))
                        Logging.Write("!! Berserking !!");
                    if (ARSettings.Instance.ArcaneTorrent && SpellManager.HasSpell("Arcane Torrent") && SpellManager.CanCast("Arcane Torrent") && Me.CurrentTarget.Distance < 8 && Me.CurrentEnergy < 90)
                        if (CastMeUp("Arcane Torrent"))
                        { Logging.Write("!! Arcane Torrent !!"); }
                    //Trinkets with an on-use ability
                    if (ARSettings.Instance.UseTrinkets && namc() && Me.Inventory.Equipped.Trinket1.Usable && Me.Inventory.Equipped.Trinket1.Cooldown <= 0)
                        if (Me.Inventory.Equipped.Trinket1.Use())
                            Logging.Write("!! TRINKET USED !!");
                    if (ARSettings.Instance.UseTrinkets && namc() && Me.Inventory.Equipped.Trinket2.Usable && Me.Inventory.Equipped.Trinket2.Cooldown <= 0)
                        if (Me.Inventory.Equipped.Trinket2.Use())
                            Logging.Write("!! TRINKET USED !!");
                    //Gloves with an on-use ability
                    if (ARSettings.Instance.UseEngineeringGloves && namc() && Me.Inventory.Equipped.Hands.Usable && Me.Inventory.Equipped.Hands.Cooldown <= 0)
                        if (Me.Inventory.Equipped.Hands.Use())
                            Logging.Write("!! GLOVES USED !!");
                }
            }

            //AoE Rotation
            if (ARSettings.Instance.AOE && addCount() > ARSettings.Instance.AoeAmount && SpellManager.HasSpell("Fan of Knives"))
            {
                if (Me.ComboPoints > 4)
                {
                    if (SpellManager.HasSpell("Crimson Tempest") && CastMeUp("Crimson Tempest"))
                        Logging.Write("Crimson Tempest");
                    if (!SpellManager.HasSpell("Crimson Tempest") && CastMeUp("Eviscerate"))
                        Logging.Write("Eviscerate");
                }
                if (Me.ComboPoints < 5)
                    if (CastMeUp("Fan of Knives"))
                        Logging.Write("          Fan of Knives");
            }

            //Single Target Rotation
            if (!ARSettings.Instance.AOE || addCount() <= ARSettings.Instance.AoeAmount || !SpellManager.HasSpell("Fan of Knives"))
            {
                //Finishers
                    if (SpellManager.HasSpell("Slice and Dice") && namc() && Me.ComboPoints > 0 && !Me.HasAura("Slice and Dice"))
                        if (CastMeUp("Slice and Dice"))
                            Logging.Write("++ Slice and Dice ++");
                    if (SpellManager.HasSpell("Envenom") && namc() && (Me.ComboPoints > 0 && Me.HasAura("Slice and Dice") && Me.ActiveAuras["Slice and Dice"].TimeLeft.TotalSeconds < 6) || (Me.ComboPoints > 4 && !Me.HasAura("Envenom") && (Me.CurrentTarget.HasAura("Rupture") && Me.CurrentTarget.ActiveAuras["Rupture"].TimeLeft.TotalSeconds > 3)))
                        if (CastMeUp("Envenom"))
                            Logging.Write("Envenom");
                    if (!SpellManager.HasSpell("Envenom") && namc() && SpellManager.HasSpell("Eviscerate") && Me.ComboPoints > 4)
                        if (CastMeUp("Eviscerate"))
                            Logging.Write("Eviscerate");

                //Combo Point Builder
                    if (SpellManager.HasSpell("Dispatch") && namc() && Me.ComboPoints < 5 && (Me.CurrentTarget.HealthPercent < 35 || Me.HasAura("Blindside")))
                        if (CastMeUp("Dispatch"))
                            Logging.Write("          Dispatch");
                    if (SpellManager.HasSpell("Mutilate") && namc() && Me.ComboPoints < 5 && Me.CurrentTarget.HealthPercent >= 35)
                        if (CastMeUp("Mutilate"))
                            Logging.Write("          Mutilate");
                    if (!SpellManager.HasSpell("Mutilate") && SpellManager.HasSpell("Sinister Strike") && namc() && Me.ComboPoints < 5)
                        if (CastMeUp("Sinister Strike"))
                            Logging.Write("          Sinister Strike");
            }
        }

        #endregion

        #region Spells

        public bool CastMeUp(string SpellName)
        {
            if (SpellManager.CanCast(SpellName))
            {
                SpellManager.Cast(SpellName);
                return true;
            }
            return false;
        }

        #endregion
    }
}